'''
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with self work for additional information
 * regarding copyright ownership.  The ASF licenses self file
 * to you under the Apache License, Version 2.0 (the
 * "License") you may not use self file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http:#www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
'''


#import java.util.*;

#import org.apache.jena.graph.Graph;
#import org.apache.jena.graph.compose.MultiUnion;
#import org.apache.jena.rdf.model.*;
#import org.apache.jena.util.FileManager;
#import org.apache.jena.vocabulary.*;

ImportManager
    public ImportManager():
    

    '''
     * A shared instance of ImportManage, used as a default by several other
     * assembler methods.
    '''
    public final static ImportManager instance = ImportManager()

    '''
     * The cache of models already read by self manager.
    '''
    protected Map<String, Graph> cache = HashMap<>()

    '''
     * Clear self ImportManager's cache.
    '''
    # param 
    # result void
    def clear(self):
        cache.clear()
    

    '''
     * Answer <code>model</code> if it has no imports, or a union model with
     * <code>model</code> as its base and its imported models as the other
     * components. The default file manager is used to load the models.
    '''
    # param Model model
    # result Model
    def withImports(self, model):
        return withImports(FileManager.getInternal(), model)
    

    '''
     * Answer <code>model</code> if it has no imports, or a union model with
     * <code>model</code> as its base and its imported models as the other
     * components. The file manager <code>fm</code> is used to load the
     * imported models.
    '''
    # param FileManager fm, Model model
    # result Model
    def withImports(self, fm, model):
        return withImports(fm, model, HashSet<String>())
    

    # param FileManager fm, Model model, Set<String> loading
    # result Model
    def withImports(self, fm, model, loading):
        StmtIterator oit = model.listStatements(null, OWL.imports, (RDFNode) null)
        StmtIterator jit = model.listStatements(null, JA.imports, (RDFNode) null)
        if (oit.hasNext() or jit.hasNext()):
            MultiUnion g = MultiUnion(new Graph[]:model.getGraph())
            addImportedGraphs(fm, loading, oit, g)
            addImportedGraphs(fm, loading, jit, g)
            return ModelFactory.createModelForGraph(g)
        else
            return model
    

    # param FileManager fm, Set<String> loading, StmtIterator oit, MultiUnion g
    # result void
    def addImportedGraphs(self, fm, loading, oit, g):
        while (oit.hasNext()):
            String path = getObjectURI(oit.nextStatement())
            if (loading.add(path)) g.addGraph(graphFor(fm, loading, path)):
        
    

    # param Statement s
    # result String
    def getObjectURI(self, s):
        RDFNode ob = s.getObject()
        if (ob.isLiteral()):
            return AssemblerHelp.getString(s)
        if (ob.isAnon()):
        raise BadObjectException(s)
        return ((Resource) ob).getURI()
    

    # param FileManager fm, Set<String> loading, String path
    # result Graph
    def graphFor(self, fm, loading, path):
        Graph already = cache.get(path)
        if (already is None):
            Graph result = withImports(fm, fm.loadModelInternal(path), loading).getGraph()
            cache.put(path, result)
            return result
        else
            return already
    

